/**
 *
 */
package soa.security.domain;

import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.ldap.odm.annotations.*;
import org.springframework.ldap.support.LdapNameBuilder;
import soa.security.Constants;

import javax.naming.Name;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author CreGu
 */
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@Entry(objectClasses = {"zjtzsw-account", "account", "zjtzsw-uid"})
public final class Account extends SoaUid {


    public static final String STAFF = "STAFF";
    /**
     * 公众个人
     */
    public static final String PERSON = "PERSON";
    /**
     * 公众单位
     */
    public static final String ORGANIZATION = "ORGANIZATION";

    private static final long serialVersionUID = -1303784899904839582L;

    @XmlTransient
    @JsonIgnore
    @Id
    private Name dn;

    @DnAttribute(value = "uid")
    private String uid;

    private String pwdAccountLockedTime;

    @Attribute(name = "userPassword")
    private String password;

    private String bid;

    private String personBid;

    private boolean disable;

    private boolean expired;

    private boolean credentialsNonExpired;

    private boolean supered;

    private boolean admined;

    private String passwordUpdateTime;

    private String loginTime;

    private String createTime;

    private int priority;

    private boolean imported;

    /**
     * 账户类型
     */
    private String accountType;

    /**
     * 账户状态
     */
    private String accountStatus;

    @XmlTransient
    @JsonIgnore
    private boolean pwdTexted;

    @XmlTransient
    @JsonIgnore
    private String pwdText;

    /**
     * 加密算法
     */
    private String algorithmName;
    /**
     *
     */
    /*
     * 导入的时候使用
	 */
    @XmlTransient
    @JsonIgnore
    @Transient
    private String organizationId;

    /*
     * 账号是否被锁定，根据pwdAccountLockedTime
     */
    @XmlTransient
    @JsonIgnore
    @Transient
    private boolean pwdLockout;

    /*
     * 对应的人员
     */
    @XmlTransient
    @JsonIgnore
    @Transient
    private Person person;

    /*
     * 密码的byte[] 表示
     */
    @XmlTransient
    @JsonIgnore
    @Transient
    private byte[] passwordByte;

    /*
     * 原来的dn，用于修改bid时用
     */
    @XmlTransient
    @JsonIgnore
    @Transient
    private String oldDn;

    public Account() {
    }

    public Account(String uid, String password, String bid, String personBid) {
        super();
        this.uid = uid;
        this.password = password;
        this.bid = bid;
        this.personBid = personBid;
    }

    public Account(String bid, String password) {
        super();
        this.bid = bid;
        this.password = password;
    }

    public static Account build(String uid, String password, String bid,
                                String personBid) {
        return new Account(uid, password, bid, personBid);
    }

    public static Account buildFromXls(String organizationId, String bid,
                                       String password, String personBid, String admin) {

        Account result = new Account(null, password, bid, personBid);
        result.setOrganizationId(organizationId);
        result.setImported(true);
        result.setPwdTexted(true);
        result.setPwdText(password);
        if ("是".equals(admin))
            result.setAdmined(true);

        return result;
    }

    public static Account buildSuper() {
        Account account = new Account(Constants.ACCOUNT_SUPER_USERNAME,
                Constants.ACCOUNT_INIT_PWD);
        account.setUid(Constants.ACCOUNT_SUPER_USERNAME);
        account.setAdmined(true);
        account.setSupered(true);

        return account;
    }

    public Name buildDn(Name baseDn) {
        return LdapNameBuilder.newInstance(baseDn).add(Constants.UID, getUid())
                .build();
    }

    public Name getDn() {
        return dn;
    }

    public void setDn(Name dn) {
        this.dn = dn;
    }

    public String getUid() {
        return uid;
    }

    public void setUid(String uid) {
        this.uid = uid;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getBid() {
        return bid;
    }

    public void setBid(String bid) {
        this.bid = bid;
    }

    public String getPersonBid() {
        return personBid;
    }

    public void setPersonBid(String personBid) {
        this.personBid = personBid;
    }

    public boolean isDisable() {
        return disable || pwdLockout;
    }

    public void setDisable(boolean disable) {
        this.disable = disable;
    }

    public boolean isExpired() {
        return expired;
    }

    public void setExpired(boolean expired) {
        this.expired = expired;
    }

    public boolean isCredentialsNonExpired() {
        return credentialsNonExpired;
    }

    public void setCredentialsNonExpired(boolean credentialsNonExpired) {
        this.credentialsNonExpired = credentialsNonExpired;
    }

    public boolean isAdmined() {
        return admined;
    }

    public void setAdmined(boolean admined) {
        this.admined = admined;
    }

    public String getPasswordUpdateTime() {
        return passwordUpdateTime;
    }

    public void setPasswordUpdateTime(String passwordUpdateTime) {
        this.passwordUpdateTime = passwordUpdateTime;
    }

    public String getLoginTime() {
        return loginTime;
    }

    public void setLoginTime(String loginTime) {
        this.loginTime = loginTime;
    }

    public String getCreateTime() {
        return createTime;
    }

    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }

    public String getOrganizationId() {
        return organizationId;
    }

    public void setOrganizationId(String organizationId) {
        this.organizationId = organizationId;
    }

    public byte[] getPasswordByte() {
        return passwordByte;
    }

    public void setPasswordByte(byte[] passwordByte) {
        this.passwordByte = passwordByte;
    }

    public String getPwdAccountLockedTime() {
        return pwdAccountLockedTime;
    }

    public void setPwdAccountLockedTime(String pwdAccountLockedTime) {
        this.pwdAccountLockedTime = pwdAccountLockedTime;
    }

    public boolean isPwdLockout() {
        return pwdLockout;
    }

    public void setPwdLockout(boolean pwdLockout) {
        this.pwdLockout = pwdLockout;
    }

    public boolean isSupered() {
        return supered;
    }

    public void setSupered(boolean supered) {
        this.supered = supered;
    }

    public int getPriority() {
        return priority;
    }

    public void setPriority(int priority) {
        this.priority = priority;
    }

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public String getOldDn() {
        return oldDn;
    }

    public void setOldDn(String oldDn) {
        this.oldDn = oldDn;
    }

    public boolean isImported() {
        return imported;
    }

    public void setImported(boolean imported) {
        this.imported = imported;
    }

    public boolean isPwdTexted() {
        return pwdTexted;
    }

    public void setPwdTexted(boolean pwdTexted) {
        this.pwdTexted = pwdTexted;
    }

    public String getPwdText() {
        return pwdText;
    }

    public void setPwdText(String pwdText) {
        this.pwdText = pwdText;
    }

    public String getAlgorithmName() {
        return algorithmName;
    }

    public void setAlgorithmName(String algorithmName) {
        this.algorithmName = algorithmName;
    }

    public String getAccountStatus() {
        return accountStatus;
    }

    public void setAccountStatus(String accountStatus) {
        this.accountStatus = accountStatus;
    }

    public String getAccountType() {
        return accountType;
    }

    public void setAccountType(String accountType) {
        this.accountType = accountType;
    }

    public boolean isReal() {
        return ("2".equals(getAccountStatus()) || "3".equals(getAccountStatus()));
    }

    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    public static class Accounts {
        protected List<Account> account = new ArrayList<Account>();

        public List<Account> getAccount() {
            return this.account;
        }

        public void addAccount(Account account) {
            this.account.add(account);
        }

        public boolean addAll(Collection<? extends Account> c) {
            return account.addAll(c);
        }
    }
}
